"""
Provides a generic SMTP client for sending
email from pspsyder appps.
"""
import smtplib
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.MIMENonMultipart import MIMENonMultipart
from email import Encoders
import mimetypes, os


class SMTPClient(object):
    """
    SMTP Client for sending mail messages
    """
    STATUS_NEW = 0
    STATUS_SRVR = 1
    STATUS_LOGIN = 2
    STATUS_SENT = 3
    STATUS_ERROR = -1
    
    STATUS_STATES = {0:'New',1:'Server Contacted',2:'Logged In',3:"Sent",-1:"Error"}
    
    def __init__(self, smtpServerName='localhost', uid=None, pwd=None, debug=0):
        """
        Initialized with the name of the server
        """
        self._server = smtpServerName
        self._uid = uid
        self._pwd = pwd
        self._debug = debug
        
    def _buildMessage(self, fromaddr, toaddrs, subject, body, filenames=[]):
        """
        builds the message object with option for Multi-Part MIME. If 
        filenames is not empty, each is assumed to be a file and is set
        as an attachment for a Multipart message.  If filenames s empty
        then a non-multipart will be created.
        """
        message = None
        # check for attachments
        if len(filenames) == 0:
            # no attachments, use Non-Multipart and
            # load er up
            message = MIMENonMultipart('text', 'plain')
            message.set_payload(body)
        else:
            # add in attachments
            message = MIMEMultipart()
            message['From'] = fromaddr
            
            # could be a string with one or more
            # comma delimited addresses or a list
            # of address.
            if toaddrs.__class__.__name__ == 'str':
                message['To'] = toaddrs
            else:
                message['To'] = ", ".join(toaddrs)
                
            # set the standard part of the message    
            message['Subject'] = subject            
            textPart = MIMEBase('text', 'plain')
            textPart.set_payload(body)
            
            message.attach(textPart)
            
            # attach each file as a new part
            for filename in filenames:
                # guess the mimetype
                mimetype = mimetypes.guess_type(filename)[0]
                if not mimetype: mimetype = 'application/octet-stream'
                maintype, subtype = mimetype.split('/')
                attachment = MIMEBase(maintype, subtype)
                attachment.set_payload(file(filename).read())
                # base64 encode for safety
                Encoders.encode_base64(attachment)
                # include filename info
                attachment.add_header('Content-Disposition', 'attachment',
                                      filename=os.path.split(filename)[1])
                message.attach(attachment)
        
        # return the message structure    
        return message
    
    def send(self, fromaddr, toaddr, subject, body, filenames=[]):
        """
        send  a message
        """
        # set up the server
        srvr = None
        rv = self.STATUS_ERROR
        try:
            srvr = smtplib.SMTP(self._server)
            srvr.set_debuglevel(self._debug)
            rv = self.STATUS_SRVR
            
            # check for login info
            # (may throw exception)
            if self._uid:
                    srvr.login(self._uid, self._pwd)
                    
            rv = self.STATUS_LOGIN
            
            # format the message 
            msg = self._buildMessage(fromaddr, toaddr, subject, body, filenames)
            
            # send it along
            sending = srvr.sendmail(fromaddr, [toaddr], msg.as_string(unixfrom=False))
            
            rv = self.STATUS_SENT
            
        finally:
            # all done, close session
            if srvr:
                srvr.quit()
    
        return rv, self.STATUS_STATES[rv]
    
# test script        
if __name__ == '__main__':
    c = SMTPClient('mail.synergies4u.com', debug=1)
    c.send('david@localhost', 'david@synergies4u.com', 'test', 'test', ['setup.py'])
    
